package com.diana.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ValueFilter;
import net.sf.cglib.beans.BeanMap;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.sql.Timestamp;
import java.text.MessageFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 *  Utils工具类
 *  @author anzhi
 *  @lastModified
 *  @history
 */
public class Utils {

    //特殊字符
    private static String special = "[ _`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]|\n|\r|\t" ;

    /**
     *  通用返回
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String message(String code, String msg, Object data) {
        JSONObject mes = new JSONObject();
        mes.put("code", code);
        mes.put("msg", msg);
        if (data != null)
            mes.put("data", data);
        return JSON.toJSONString(mes,filter,SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     *  通用返回(分页)
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String message(String code, String msg, Object data,long total){
        JSONObject mes = new JSONObject();
        mes.put("code",code);
        mes.put("mes",msg);
        if(data != null)
            mes.put("data",data);
        if(total != -1)
            mes.put("total",total);
        return JSON.toJSONString(mes,filter,SerializerFeature.DisableCircularReferenceDetect);
    }

    public static ValueFilter filter = new ValueFilter() {
        public Object process(Object obj, String s, Object v) {
            if (v == null)
                return "";
            return v;
        }
    };

    /**
     *  判断字符串是否为null或""
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean isNullOrEmpty(String s){
        return s == null || "".equals(s.trim());
    }

    /**
     *  判断字符串是否为英文或数字
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean checkEngStr(String s,int minSize,int maxSize){
        if(isNullOrEmpty(s))
            return false;
        if(containsSpecialChar(s))
            return false;
        if(containsCNcode(s))
            return false;
        if(s.length()<minSize)
            return false;
        if (s.length()>maxSize)
            return false;
        return true;
    }

    /**
     *  toString
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String toString(Object o){
        if(o==null){
            return "";
        }else if(o instanceof Timestamp){
            return o.toString().substring(0, 19);
        }else{
            return o.toString();
        }
    }

    /**
     *  toInteger
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static Integer toInteger(Object o){
        Integer i = null;
        try {
            i = Integer.valueOf(toString(o));
        } catch (Exception e) {
            return i;
        }
        return i;
    }

    /**
     *  获取Cookie
     *  @param request
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static Map<String,Cookie> getCookies(HttpServletRequest request){
        Map<String,Cookie> CookieMap = new HashMap<String,Cookie>();
        Cookie[] cookies = request.getCookies();
        if(null != cookies){
            for(Cookie cookie : cookies){
                CookieMap.put(cookie.getName(), cookie);
            }
        }
        return CookieMap;
    }

    /**
     *  根据name获取在request头中或者Cookie中或者request body中的值
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String getCookisValue(HttpServletRequest request,String name){
        String value = request.getHeader(name);
        if(isNullOrEmpty(value)){
            Cookie cookie = getCookies(request).get(name);
            if(cookie ==null){
                return request.getParameter(name);
            }
            return cookie.getValue();
        }
        return value;
    }

    /**
     *  获取精确到秒的时间戳
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static int getSecondTimestamp(Date date){
        if(date==null){
            return 0;
        }
        String timestamp = String.valueOf(date.getTime());
        int length = timestamp.length();
        if(length>3){
            return Integer.valueOf(timestamp.substring(0, length-3));
        }
        return 0;
    }

    /**
     *  获取16位ID
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String getUUID(){
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     *  获取数字Id
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static long getNumId(){
        byte [] bytes = UUID.randomUUID().toString().replace("-", "").getBytes();
        ByteBuffer buffer = ByteBuffer.allocate(8);
        buffer.put(bytes, 0, 8);
        buffer.flip();
        return buffer.getLong();
    }

    /**
     *  时间格式转换
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String DateFormat(Date d, String f){
        SimpleDateFormat sdf = new SimpleDateFormat(f, Locale.ENGLISH);
        if (d == null)
            return null;
        return sdf.format(d);
    }

    /**
     *  时间格式转换
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String DateFormat(Timestamp t, String f) {
        if (t == null)
            return "";
        SimpleDateFormat sdf = new SimpleDateFormat(f);
        Date date = new Date(t.getTime());
        return sdf.format(date);
    }

    /**
     *  字符串转Date
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static Date toDate(String d, String f) {
        SimpleDateFormat sdf = new SimpleDateFormat(f);
        try {
            return sdf.parse(d);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     *  获取IP地址
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String getRemoteHost(HttpServletRequest request){
        String ip = request.getHeader("x-forwarded-for");
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
            ip = request.getHeader("Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
            ip = request.getRemoteAddr();
            if(ip.equals("127.0.0.1") || ip.equals("0:0:0:0:0:0:0:1")){
                //根据网卡取本机配置的IP
                InetAddress inet=null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                ip= inet.getHostAddress();
            }
        }
        //对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if(ip!=null && ip.length()>15){ //"***.***.***.***".length() = 15
            if(ip.indexOf(",")>0){
                ip = ip.substring(0,ip.indexOf(","));
            }
        }
        return ip;
    }

    /**
     *  response写入文本
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static void write(HttpServletResponse response,String s){
        PrintWriter writer;
        try {
            response.setContentType("text/html");
            writer = response.getWriter();
            writer.write(s);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void writeJson(HttpServletResponse response,JSONObject jo){
        PrintWriter writer;
        try {
            response.setContentType("application/json");
            writer = response.getWriter();
            writer.write(jo.toJSONString());
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     *  response写入文件
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static void downFile(HttpServletResponse response,File file,Map<String, byte[]>files){
        try{
            response.setContentType("application/x-msdownload");
            response.setHeader("Content-Disposition", "attachment; filename=" + new String(file.getName().getBytes(), "ISO-8859-1"));
            byte [] bytefile = getBytes(file);           //文件转成byte[]
            response.getOutputStream().write(bytefile);  //把byte[]写进流，给response返回
            response.getOutputStream().flush();
            response.getOutputStream().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     *  文件转byte[]
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static byte[] getBytes(File file){
        byte[] buffer = null;
        try {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1000];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }

    /**
     *  多个文件打成zip
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static void writeZip(File[] srcfile, File zipfile) {
        byte[] buf=new byte[8192];
        ZipOutputStream out=null;
        try {
            out=new ZipOutputStream(new FileOutputStream(
                    zipfile));
            for (int i=0; i < srcfile.length; i++) {
                FileInputStream in=new FileInputStream(srcfile[i]);
                out.putNextEntry(new ZipEntry(srcfile[i].getName()));
                int len;
                while ((len=in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
                out.closeEntry();
                in.close();
            }
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     *  判断是否Json
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean isJson(String jsonStr){
        boolean flag = true;
        try{
            JSONObject.parse(jsonStr);
        }catch(Exception e){
            flag = false;
        }
        return flag;
    }

    /**
     *  判断是否JsonArray
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean isJsonArray(String jsonStr){
        try{
            JSONObject.parseArray(jsonStr);
            return true;
        }catch(Exception e){
            return false;
        }
    }

    /**
     *  mapToJson
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static JSONObject mapToJson(Map<String,Object> map){
        return (JSONObject) JSON.toJSON(map);
    }

    /**
     *  listToJsonArray
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static JSONArray listToJsonArray(List<Map<String,Object>> list){
        return (JSONArray) JSON.toJSON(list);
    }

    /**
     *  Object转Json
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static JSONObject toJson(Object o){
        if(o==null){
            return null;
        }
        try{
            return JSONObject.parseObject(toString(o));
        }catch(Exception e){
            return null;
        }
    }

    /**
     *  Object转JsonArray
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static JSONArray toJsonArray(Object o){
        if(o==null){
            return null;
        }
        try{
            return JSONObject.parseArray(toString(o));
        }catch(Exception e){
            return null;
        }
    }

    /**
     *  map2bean
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static <T> T map2bean(Map<String,Object> map,Class<T> clz) throws Exception{
        if (map==null) {
            return null;
        }
        T bean = null;
        try {
            String tStr = mapToJson(map).toJSONString();
            bean = JSONObject.parseObject(tStr, clz);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  bean;
    }

    /**
     *  bean2Json
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static JSONObject bean2Json(Object bean){
        if(bean!=null){
            Field[] fields = bean.getClass().getDeclaredFields();
            Map<String,Object> map = new HashMap<String,Object>();
            for(Field field : fields){
                String fieldName = field.getName();
                if(getValueByFieldName(fieldName,bean)!=null){
                    map.put(fieldName, getValueByFieldName(fieldName, bean).toString());
                }
            }
            return mapToJson(map);
        }else{
            return new JSONObject();
        }
    }

    /**
     *  beanToMap
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static <T> Map<String, Object> beanToMap(T bean) {
        Map<String, Object> map = new HashMap<String, Object>();
        if (bean != null) {
            BeanMap beanMap = BeanMap.create(bean);
            for (Object key : beanMap.keySet()) {
                map.put(key + "", beanMap.get(key));
            }
        }
        return map;
    }

    /**
     *  mapToBean
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static <T> T mapToBean(Map<String, Object> map, T bean) {
        BeanMap beanMap = BeanMap.create(bean);
        beanMap.putAll(map);
        return bean;
    }

    /**
     *  jsonToMap
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static Map<String, Object> jsonToMap(JSONObject obj) {
        Set<?> set = obj.keySet();
        Map<String, Object> map = new HashMap<String, Object>(set.size());
        for (Object key : obj.keySet()) {
            Object value = obj.get(key);
            if (value instanceof JSONArray) {
                map.put(key.toString(), jsonToList((JSONArray) value));
            } else if (value instanceof JSONObject) {
                map.put(key.toString(), jsonToMap((JSONObject) value));
            } else {
                map.put(key.toString(), obj.get(key));
            }
        }
        return map;
    }

    /**
     *  json2map(解决排序)
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static Map<String,Object> json2map(String json){
        Map<String,Object> map = JSON.parseObject(json, LinkedHashMap.class, Feature.OrderedField);
        return map;
    }

    /**
     *  jsonToList
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static List<Object> jsonToList(JSONArray jsonArr) {
        List<Object> list = new ArrayList<Object>();
        for (Object obj : jsonArr) {
            if (obj instanceof JSONArray) {
                list.add(jsonToList((JSONArray) obj));
            } else if (obj instanceof JSONObject) {
                list.add(jsonToMap((JSONObject) obj));
            } else {
                list.add(obj);
            }
        }
        return list;
    }

    /**
     *  根据属性名获取该类此属性的值
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static Object getValueByFieldName(String fieldName,Object object){
        String firstLetter = fieldName.substring(0, 1).toUpperCase();
        String getter = "get" + firstLetter + fieldName.substring(1);
        try {
            Method method = object.getClass().getMethod(getter, new Class[] {});
            Object value = method.invoke(object, new Object[] {});
            return value;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     *  验证
     *  v为正则表达式
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean checkIsValid(String s,String v){
        Pattern p = Pattern.compile(v);
        Matcher m = p.matcher(s);
        return m.matches();
    }

    /**
     *  手机验证
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean checkPhone(String phone){
        if(phone==null){
            return false;
        }
        return checkIsValid(phone, "^[1][3,4,5,6,7,8][0-9]{9}$");
    }

    /**
     *  邮箱验证
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean checkEmail(String email){
        if(email==null){
            return false;
        }
        String checkValue = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
        return checkIsValid(email,checkValue);
    }

    /**
     *  是否包含以下特殊字符
     *  [ _`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]|\n|\r|\t
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean containsSpecialChar(String s) {
        Pattern p = Pattern.compile(special);
        Matcher m = p.matcher(s);
        return m.find();
    }

    /**
     *  是否包含中文
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean containsCNcode(String s){
        Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m = p.matcher(s);
        return m.find();
    }

    /**
     *  是否为中文
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean isCNcode(String s){
        if(isNullOrEmpty(s))
            return false;
        String reg = "[\\u4e00-\\u9fa5]+";
        return s.matches(reg);
    }

    /**
     *  过滤特殊字符
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String specialFilter(String str) {
        String regEx = "[`~!@#$%^&*()\\-+={}':;,\\[\\].<>/?￥%…（）_+|【】‘；：”“’。，、？\\s]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.replaceAll("").trim();
    }

    /**
     *  判断字符串是否为数字
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean isNumInt(String s){
        if(isNullOrEmpty(s))
            return false;
        String checkValue ="[0-9]+";
        return checkIsValid(s,checkValue);
    }

    /**
     *  判断字符串是否为数字
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean isNumDouble(String s){
        if(isNullOrEmpty(s))
            return false;
        String checkValue ="^\\d+(\\.\\d+)?$";
        return checkIsValid(s,checkValue);
    }

    /**
     *  判断是否为时间格式
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean isDate(String s){
        if(isNullOrEmpty(s)){
            return false;
        }
        String[] formats = { "yyyy-MM-dd HH:mm:ss SSS", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH",
                "yyyy-MM-dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH", "yyyy/MM/dd", "yyyy年MM月dd日" };
        for(String format : formats){
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            try {
                sdf.parse(s);
                return true;
            } catch (ParseException e) {
                continue;
            }
        }
        return false;
    }

    /**
     *  Object转BigDecimal
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static BigDecimal toBigDecimal(Object o){
        BigDecimal b = BigDecimal.ZERO;
        try{
            b = new BigDecimal(toString(o));
        }catch(Exception e){
            return b;
        }
        return b;
    }

    /**
     *  判断对象是否为空
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean isEmpty(Object o){
        if(o==null)
            return true;
        if(o instanceof String)
            return isNullOrEmpty((String)o);
        if (o instanceof Collection && ((Collection<?>) o).isEmpty())
            return true;
        if (o.getClass().isArray() && Array.getLength(o) == 0)
            return true;
        if (o instanceof Map && ((Map<?, ?>) o).isEmpty())
            return true;

        return false;
    }

    /**
     *  判断多个对象中是否有空对象
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean isEmptyObj(Object... arr){
        boolean flag =false;
        for (Object obj : arr) {
            if (isEmpty(obj)) {
                return true;
            }
        }
        return flag;
    }

    /**
     *  判断字符串是否相等，不为空
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean equals(String s1,String s2){
        if(isEmptyObj(s1,s2)){
            return false;
        }
        if(s1.equals(s2)){
            return true;
        }
        return false;
    }

    /**
     *  获取文件拓展名
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String getFileExtend(MultipartFile file){
        if(file==null){
            return "";
        }
        String fileName = file.getOriginalFilename();
        String prefix = fileName.substring(fileName.lastIndexOf(".") + 1);
        return prefix;
    }

    /**
     *  如果字符串用第二个参数结尾，则去掉
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String trimEnd(String s,String v){
        if(s.endsWith(v)){
            s = s.substring(0,s.length()-v.length());
        }
        return s;
    }

    /**
     *  如果字符串用第二个参数开头，则去掉
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String trimStart(String s,String v){
        if(s.startsWith(v)){
            s = s.substring(v.length(),s.length());
        }
        return s;
    }

    /**
     *  isBigDecimal
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean isBigDecimal(Object obj) {
        try {
            new BigDecimal(Utils.toString(obj));
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     *  读取BufferedReader
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String readToEnd(BufferedReader read){
        String result = "";
        String line;
        try {
            while ((line = read.readLine()) != null) {
                result += line;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     *  根据身份证获取年龄
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static int getAgebyCard(String IdNO) {
        int leh = IdNO.length();
        int age = 0;
        if (leh == 18) {
            String yyy = IdNO.substring(6, 10); // 出生的年份
            String now = DateFormat(new Date(), "yyyy");
            age = Integer.parseInt(now) - Integer.parseInt(yyy);
        }
        if (leh == 15) {
            String yyy = "19" + IdNO.substring(6, 8); // 出生的年份
            String now = DateFormat(new Date(), "yyyy");
            age = Integer.parseInt(now) - Integer.parseInt(yyy);
        }
        return age;
    }

    /**
     *  验证18位身份证
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean checkIDCard18(String Id) {
        long n = 0;
        try {
            n = Long.parseLong(Id.substring(0, 17));
            if (n < Math.pow(10, 16))
                return false;
            n = Long.parseLong(Id.replace("x", "0").replace("X", "0"));
        } catch (Exception e) {
            return false;
        }
        String address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
        if (address.indexOf(Id.substring(0, 2)) == -1) {
            return false;// 省份验证
        }
        return true;// 符合GB11643-1999标准
    }

    /**
     *  验证15位身份证
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean checkIDCard15(String Id) {
        long n = 0;
        try {
            n = Long.parseLong(Id);
            if (n < Math.pow(10, 14))
                return false;
        } catch (Exception e) {
            return false;
        }
        String address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
        if (address.indexOf(Id.substring(0, 2)) == -1) {
            return false;// 省份验证
        }
        String birth = Id.substring(6, 8) + "-" + Id.substring(8, 10) + "-" + Id.substring(10, 12);
        try {
            Utils.toDate("19" + birth, "yyyy-MM-dd");
        } catch (Exception e) {
            return false;// 生日验证
        }
        return true;// 符合15位身份证标准
    }

    /**
     *  验证身份证
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static boolean checkCardNO(String str) {
        if (str.length() == 18) {
            boolean check = checkIDCard18(str);
            return check;
        } else if (str.length() == 15) {
            boolean check = checkIDCard15(str);
            return check;
        } else {
            return false;
        }
    }

    /**
     *  获取星座
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    @SuppressWarnings("deprecation")
    public static String getZodiac(Date date) {
        if (date == null)
            return "";
        int month = date.getMonth() + 1;
        int day = date.getDate();
        String[] starArr = { "摩羯座", "水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座",
                "摩羯座" };
        int[] DayArr = { 20, 19, 21, 20, 21, 22, 23, 23, 23, 24, 23, 22 };

        String star = day < DayArr[month - 1] ? starArr[month - 1] : starArr[month];
        return star;
    }

    /**
     *  多图片上传获取multiRequest对象
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static MultipartHttpServletRequest getMultiRequest(HttpServletRequest request){
        if(request instanceof MultipartHttpServletRequest){
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            return multiRequest;
        }
        return null;
    }

    /**
     *  MD5加密
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public final static String MD5(String s) {
        s = MessageFormat.format("%$#&{0}!&", s);
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
        try {
            byte[] strTemp = s.getBytes();
            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(strTemp);
            byte[] md = mdTemp.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     *  二进制转十六进制
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String parseByte2HexStr(byte buf[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    /**
     *  十六进制转二进制
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1) {
            return null;
        }
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2),
                    16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }

    /**
     * 编码格式
     */
    private static final String ENCODING = "UTF-8";
    /**
     * 加密算法
     */
    public static final String KEY_ALGORITHM = "AES";
    /**
     * 签名算法
     */
    public static final String SIGN_ALGORITHMS = "SHA1PRNG";


    /**
     *  Aes加密
     *  @param content:加密内容
     *  @param key:加密密钥
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String AesEncrypt(String content, String key) {
        try {
            KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
            SecureRandom random = SecureRandom.getInstance(SIGN_ALGORITHMS);
            random.setSeed(key.getBytes(ENCODING));
            kgen.init(128, random);
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, KEY_ALGORITHM);
            Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
            byte[] byteContent = content.getBytes(ENCODING);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            byte[] byteRresult = cipher.doFinal(byteContent);
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < byteRresult.length; i++) {
                String hex = Integer.toHexString(byteRresult[i] & 0xFF);
                if (hex.length() == 1) hex = '0' + hex;
                sb.append(hex.toUpperCase());
            }
            return sb.toString();
        } catch (Exception e) {
            e.toString();
        }
        return null;
    }

    /**
     *  Aes解密
     *  @param content:解密内容
     *  @param key:解密密钥
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String AesDecrypt(String content, String key) {
        if (content.length() < 1) return null;
        byte[] byteRresult = new byte[content.length() / 2];
        for (int i = 0; i < content.length() / 2; i++) {
            int high = Integer.parseInt(content.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(content.substring(i * 2 + 1, i * 2 + 2), 16);
            byteRresult[i] = (byte) (high * 16 + low);
        }
        try {
            KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
            SecureRandom random = SecureRandom.getInstance(SIGN_ALGORITHMS);
            random.setSeed(key.getBytes(ENCODING));
            kgen.init(128, random);
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, KEY_ALGORITHM);
            Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            byte[] result = cipher.doFinal(byteRresult);
            return new String(result, ENCODING);
        } catch (Exception e) {
            e.toString();
        }
        return null;
    }

    /**
     *  手机或者邮箱隐藏部分
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static String phoneOrEmailToHide(String s) {
        if (Utils.checkPhone(s)) {
            s = s.substring(0,s.length()-(s.substring(3)).length())+"****"+s.substring(7);
        } else if (Utils.checkEmail(s)) {
            String[] arr = s.split("@");
            String temp = arr[0];
            s = temp.length()>=6? temp.substring(0,temp.length()-4)+"****"+arr[1]:temp+arr[1];
        }
        return s;
    }

    /**
     *  时间加减
     *  @param type 如 Calendar.DATE
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static Date addTime(Date d, int m, int type) {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(d);
        gc.add(type, m);
        return gc.getTime();
    }

    /**
     *  日期相减返回day
     *  @author anzhi
     *  @lastModified
     *  @history
     */
    public static int getDays(Date s,Date e){
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(s);
        c2.setTime(e);
        long mill = c2.getTimeInMillis() - c1.getTimeInMillis();
        if(mill<0){
            return -1;
        }
        mill = mill / 1000 / 60 / 60 / 24;
        return Integer.parseInt("" + mill);
    }

    /**
     * 获取request
     * @return
     */
    public static HttpServletRequest getRequest() {
        HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        return req;
    }

    /**
     * 获取Response
     * @return
     */
    public static HttpServletResponse getResponse() {
        HttpServletResponse resp = ((ServletWebRequest) RequestContextHolder.getRequestAttributes()).getResponse();
        return resp;
    }

    /**
     *  补全位数
     *  @author anzhi
     *  @history
     */
    public static String getSerialNum(String str,int length){
        StringBuffer sb = new StringBuffer();
        int n = length-str.length();
        for (int i=0;i<n;i++){
            sb.append("0");
        }
        sb.append(str);
        return sb.toString();
    }

    /**
     * 返回日时分秒
     * @param second
     * @return
     */
    public static String secondToTime(long second) {
        long days = second / 86400;//转换天数
        second = second % 86400;//剩余秒数
        long hours = second / 3600;//转换小时数
        second = second % 3600;//剩余秒数
        long minutes = second / 60;//转换分钟
        second = second % 60;//剩余秒数
        if (0 < days){
            return days + "天"+hours+"小时"+minutes+"分"+second+"秒";
        }else {
            return hours+"小时"+minutes+"分"+second+"秒";
        }
    }

    public static void main(String[] args) {

        int i = (int) (Math.random()*1000)+1;
        System.out.println(i);
    }

    public static String secondToTimeNoDay(long second) {
        long hours = second / 3600;//转换小时数
        second = second % 3600;//剩余秒数
        long minutes = second / 60;//转换分钟
        second = second % 60;//剩余秒数
        return hours+"小时"+minutes+"分"+second+"秒";
    }
}

